package ext.tianma.bom.util;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.ptc.core.lwc.client.commands.LWCCommands;
import com.ptc.core.lwc.common.BaseDefinitionService;
import com.ptc.core.lwc.common.view.AttributeDefinitionReadView;
import com.ptc.core.lwc.common.view.ConstraintDefinitionReadView;
import com.ptc.core.lwc.common.view.EnumerationDefinitionReadView;
import com.ptc.core.lwc.common.view.EnumerationEntryReadView;
import com.ptc.core.lwc.common.view.PropertyValueReadView;
import com.ptc.core.lwc.server.LWCAbstractAttributeTemplate;
import com.ptc.core.lwc.server.cache.db.TypeDefinitionDBService;
import com.ptc.core.meta.common.DiscreteSet;
import com.ptc.core.meta.container.common.impl.DiscreteSetConstraint;
import com.ptc.netmarkets.model.NmOid;

import wt.access.NotAuthorizedException;
import wt.fc.ObjectIdentifier;
import wt.inf.container.WTContainerException;
import wt.method.RemoteAccess;
import wt.method.RemoteMethodServer;
import wt.services.ServiceFactory;
import wt.util.WTException;

public class EnumerationUtil implements RemoteAccess {

	public static String getEnumerationDisplayValue( String enumerationTypeName , String innerValue ){
		Map<String,String> enumerationValues = getEnumerationValues( enumerationTypeName ) ;
		
		String enumerationDisplayValue = enumerationValues.get( innerValue ) ;
		
		return enumerationDisplayValue ;
	}
	
	public static Map<String,String> getEnumerationValues( String enumerationTypeName ) {
		Map<String,String> enumerationValueMap = new HashMap<String,String>();
		
		try{
			BaseDefinitionService seviec = (BaseDefinitionService)ServiceFactory.getService(BaseDefinitionService.class);
			
			EnumerationDefinitionReadView view = seviec.getEnumDefView( enumerationTypeName );
			
			Map<String, EnumerationEntryReadView> map = view.getAllEnumerationEntries();
			
			Iterator<String> keyIte = map.keySet().iterator();
			
			while ( keyIte.hasNext()) {
				String key = keyIte.next();
				
				if( key ==null ) {
					continue;
				}
				
				EnumerationEntryReadView readview= map.get( key );
				
				if(readview==null) {
					continue;
				}
				
				if (readview.getPropertyValueByName("selectable").getValue().toString().equals("true")) {
					PropertyValueReadView propreadview = readview.getPropertyValueByName("displayName");
					if(propreadview==null||propreadview.getValueAsString()==null) {
						continue;
					}
					enumerationValueMap.put(key,propreadview.getValueAsString());
				}
			}
		} catch (NotAuthorizedException e) {
			e.printStackTrace();
		} catch (WTContainerException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		}finally{
			
		}
		
		return enumerationValueMap ;
	}

	
	public static void main(String[] args) {
		if( args != null && args[0] != null ){
			if ( ! RemoteMethodServer.ServerFlag ) {
				System.out.println( "Debug   RemoteMethodServer..." );
				String method = "getEnumerationValues";			
			
				try {
					RemoteMethodServer.getDefault().invoke(method, EnumerationUtil.class.getName() , null,
							new Class[] { String.class }, new Object[] { args[0] });
					System.out.println( "Debug  end  RemoteMethodServer..." );
				} catch (RemoteException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}else{
				System.out.println( "Debug   importParts..." );
				getEnumerationValues( args[0] ) ;
				System.out.println( "Debug   end  importParts..." );
			}
		}
	}
	/**
	 * 根据类型和属性获取合法值列表
	 * @return
	 */
	public static List<String> getTypeLegalValues(String typeName, String attrName) throws WTException {
		List<String> valueList = new ArrayList<String>();
		LWCAbstractAttributeTemplate td = TypeDefinitionDBService.newTypeDefinitionDBService().getTypeDefinition(typeName);
		NmOid nmOid = NmOid.newNmOid(ObjectIdentifier.newObjectIdentifier(td.toString()));

		//获取类型中的所有属性定义
		ArrayList<? extends Object> adrvs = LWCCommands.getTypeAttributes(nmOid.toString());
		for(Object object:adrvs) {
			if(object instanceof AttributeDefinitionReadView) {
				AttributeDefinitionReadView adrv = (AttributeDefinitionReadView)object;
				//比较相同的属性定义
				if(adrv.getAttributeTypeIdentifier().getAttributeName().equals(attrName)) {
					//获取所有约束
					Collection<ConstraintDefinitionReadView> constraints = adrv.getAllConstraints();
					Iterator<ConstraintDefinitionReadView> iter = constraints.iterator();
					for(ConstraintDefinitionReadView constraint: constraints) {
						String defClassName = constraint.getRule().getRuleClassname();
						//获取合法值类型
						if(defClassName.equals(DiscreteSetConstraint.class.getName())) {
							Serializable ruleData = constraint.getRuleData();
							if(ruleData!=null && ruleData instanceof DiscreteSet) {
								DiscreteSet set  = (DiscreteSet)ruleData;
								Object[] elements = set.getElements();
								for(Object element:elements) {
									if(element instanceof String) {
										String value = (String)element;
										valueList.add(value);
									}
								}
								break;
							}
						}
					}
					break;
				}
			}
		}
		return valueList;
	}
	
	/**
	 * 获取枚举值根据显示名称-内部名称
	 * @param enumerationTypeName
	 * @return
	 */
	public static Map<String,String> getEnumerationValues2( String enumerationTypeName ) {
		Map<String,String> enumerationValueMap = new HashMap<String,String>();
		try{
			BaseDefinitionService seviec = (BaseDefinitionService)ServiceFactory.getService(BaseDefinitionService.class);
			EnumerationDefinitionReadView view = seviec.getEnumDefView( enumerationTypeName );
			Map<String, EnumerationEntryReadView> map = view.getAllEnumerationEntries();
			Iterator<String> keyIte = map.keySet().iterator();
			while ( keyIte.hasNext()) {
				String key = keyIte.next();
				if( key ==null ) {
					continue;
				}
				EnumerationEntryReadView readview= map.get( key );
				if(readview==null) {
					continue;
				}
				if (readview.getPropertyValueByName("selectable").getValue().toString().equals("true")) {
					PropertyValueReadView propreadview = readview.getPropertyValueByName("displayName");
					if(propreadview==null||propreadview.getValueAsString()==null) {
						continue;
					}
					enumerationValueMap.put(propreadview.getValueAsString(), key);
				}
			}
		} catch (NotAuthorizedException e) {
			e.printStackTrace();
		} catch (WTContainerException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		}finally{
			
		}
		
		return enumerationValueMap ;
	}
	/**
	 * 根据枚举名和显示名称获得内部名称
	 * @param enumerationTypeName
	 * @param innerValue
	 * @return
	 */
	public static String getEnumerationDisplayValue2( String enumerationTypeName , String displayname ){
		Map<String,String> enumerationValues = getEnumerationValues( enumerationTypeName ) ;
		
		String innerValue = enumerationValues.get(displayname) ;
		
		return innerValue ;
	}
}
